#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
#include "kernel/fcntl.h"

char* get_name(char *path)
{
  char *p;
  // Find first character after last slash.
  for(p=path+strlen(path); p >= path && *p != '/'; p--);
  
  // skip '/'
  p++;

  return p;
}

void find(char * path, char * name){
  char buf[512], *p;
  int fd;
  struct dirent de;
  struct stat st;

  if((fd = open(path, O_RDONLY)) < 0){
    fprintf(1, "find: cannot open %s\n", path);
    return;
  }

  if(fstat(fd, &st) < 0){
    fprintf(1, "find: cannot stat %s\n", path);
    close(fd);
    return;
  }

  switch(st.type){
  case T_DEVICE:
  case T_FILE:
    if (strcmp(name, get_name(path) ) == 0){
      printf("%s\n", path);
    }else{
      // printf("not find %s\n", path);
    }
    break;

  case T_DIR:
    // 预先判断长度是否够
    if(strlen(path) + 1 + DIRSIZ + 1 > sizeof(buf)){
      printf("find: path too long\n");
      break;
    }

    strcpy(buf, path);
    p = buf+strlen(buf);
    *p++ = '/'; // 添加一个斜杠

    while(read(fd, &de, sizeof(de)) == sizeof(de)){
      
      if(de.inum == 0){
        continue;
      }

      // printf("de.name %s\n",de.name);
      
      if( strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0){
        continue;
      }
      
      // 拷贝文件名
      memmove(p, de.name, DIRSIZ);
      p[DIRSIZ] = 0;

      if(stat(buf, &st) < 0){
        printf("find: cannot stat %s\n", buf);
        continue;
      }

      find(buf, name);
    }

    break;
  }
  close(fd);
}
int
main(int argc, char *argv[])
{

  if(argc != 3){
    printf("find usage example: find . b \n");
    exit(1);
  }
  find(argv[1], argv[2]);
  exit(0);
}
